import logging
import time

from app import app, redis_client, redis_ready,set_redis_error
from flask import request,g,make_response
from app.util.jwt_tool import verify_token
from app.util.result import Result
from app.models import User
from app.enums.enums import UserStatusEnum
from app.util.log_utils import add_log_event
import threading
"""
拦截器，拦截请求，校验jwt令牌
"""
# 配置日志记录器
logger = logging.getLogger(__name__)

# 在每次请求处理之前运行
@app.before_request
def before():
    # 不进行登录校验的路径
    g.start_time = time.time()
    special_paths = ['/user/login', '/user/register', '/house/getHouseList', '/house/getHouseDetail']
    # 获取请求路径
    path = request.path
    if path not in special_paths and not path.startswith('/static'): # 访问静态文件不拦截
        # 获取请求头中的token
        token = request.headers.get('Authorization')
        err_res=make_response()
        err_res.status_code=401
        if not token:
            return err_res
        # 验证token
        payload = verify_token(token)
        if payload == 0 or payload == 1:
            return err_res
        # if path == '/user/checkLogin':
        #     user = User.query.filter_by(id=payload['id']).first()
        #     if user is None:
        #         return Result.fail(message='用户不存在')
        #     if user.status != UserStatusEnum.NORMAL.value:
        #         return Result.fail(message='用户已被封禁')
        #     return Result.success(data={
        #         'id': payload['id'],
        #         'identity': payload['identity'],
        #     })
        # 将payload保存到全局变量中，供后续使用
        app.payload = payload


# 在每次请求处理之后运行
@app.after_request
def after(response):
    # print("这是每次请求处理后的操作")
    # 记录请求接口信息
    # record_interface(g.start_time,request.path,int(response.status.split()[0]))
    threading.Thread(target=record_interface,args=(g.start_time,request.path,int(response.status.split()[0]))).start()
    return response


# 在每次请求处理之后运行，不管是否有未处理的异常
@app.teardown_request
def teardown(exception):
    # print("这是每次请求处理结束后的操作，无论是否有异常")
    if exception:
        try:
            # 记录未处理的异常到日志
            add_log_event("未处理的异常", str(exception))
        except Exception as log_error:
            # 记录日志失败的情况，避免掩盖原始异常
            logger.error(f"记录请求异常失败: {str(log_error)}")
            logger.exception(exception)  # 记录原始异常堆栈


# 记录请求的接口的次数和总时间
def record_interface(start_time, path,code):
    try:
        if redis_ready:
            elapsed_time = int((time.time() - start_time)*1000)

            one_day_in_seconds = 86400 # 24小时

            # 检查是否为首次记录（以interface_counts为例）
            is_first_record = not redis_client.exists('interface_counts')

            with redis_client.pipeline() as pipe:
                # 原子性地增加计数
                pipe.hincrby('interface_counts', path, 1)

                if code < 500:
                    pipe.hincrby('interface_right_counts', path, 1)

                # 原子性地增加总耗时
                pipe.hincrbyfloat('interface_times', path, elapsed_time)

                # 记录最近一次响应时间
                pipe.hset('interface_last_times', path, elapsed_time)

                # 仅在首次记录时设置过期时间
                if is_first_record:
                    pipe.expire('interface_counts', one_day_in_seconds)
                    pipe.expire('interface_right_counts', one_day_in_seconds)
                    pipe.expire('interface_times', one_day_in_seconds)
                    pipe.expire('interface_last_times', one_day_in_seconds)

                pipe.execute()

    except Exception as e:
        logger.error(f"Redis记录接口失败: {str(e)}")
        set_redis_error()

